package netbay;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;

public class Worker implements Runnable {

	private String fileName;
	public String cmd;
	private String attachName;
	private String ctrlName;
	private String reDo = "";
	FileDao fileMng = null;

	public Worker(String getFileName, String getCmd) {
		fileName = getFileName;
		cmd = getCmd;

		fileMng = new FileDao();
	}

	public Worker(String ctrl, String attach, String getCmd) {
		attachName = attach;
		ctrlName = ctrl;
		cmd = getCmd;

		fileMng = new FileDao();
	}

	public Worker(String attach, String re, String tmp1, String getCmd) {
		attachName = attach;
		cmd = getCmd;

		fileMng = new FileDao();
	}

	// @Override
	public void run() {
		if (cmd.equalsIgnoreCase(WorkerManager.TCDRecvCmd)) {
			ctrlName = fileName;
			recvTCD();

		} else if (cmd.equalsIgnoreCase(WorkerManager.JPMCRecvCmd)) {
			attachName = fileName;
			recvJPMC();
		}
	}

	private void recvTCD() {
		File ctrlFile = new File(WorkerManager.TCDRecvDir + "/" + ctrlName);

		String converId = TransactionLog.getConverId(ctrlFile);
		TransactionLog log = TransactionLog.convertTcdCtrlFile(ctrlFile);
		TransactionTraffic traffLog = TransactionTraffic
				.convertTcdCtrlFile(ctrlFile);

		// check error task cannot covert Ctrl file
		if (log == null) {
			WorkerManager.reportId(converId, cmd);
			return;
		} else {
			attachName = log.getTcdAttach();
			// need to check if attach file are existed or not
			File attach = new File(WorkerManager.TCDRecvDir + "/" + attachName);
			if (attach.exists()) {
				TransactionLog doBefore = new TransactionLog();
				TransactionManager manager = new TransactionManager();
				TransactionLog registeredLog = null;
				Integer id = null;
				if ((log.getActionType().equals(WorkerManager.ActionTCDToBank))
						|| (log.getActionType()
								.equals(WorkerManager.ActionRDToBank))) {
					// check if it was process before
					doBefore = manager.findTransactionByConverId(log
							.getConverId());
					if (doBefore == null) {
						id = manager.saveTransaction(log);
						if (id == null) {
							WorkerManager.reportId(converId, cmd);
							return;
						} else {
							traffLog.setTransactionId(id);
							registeredLog = manager.findTransactionById(id);

							if (log.getActionType() != null
									&& log.getActionType().equals(
											WorkerManager.ActionTCDToBank)) {
								String sendFileName = convertTCDToJPMC(attachName);
								traffLog.setConvertFile(sendFileName);
								traffLog.setType("TCD");
								registeredLog.setTimeEntry(
										TransactionManager.recvTcdStatus,
										traffLog, "");
								sendJPMC(registeredLog, traffLog, "");

							} else if (log.getActionType() != null
									&& log.getActionType().equals(
											WorkerManager.ActionRDToBank)) {
								traffLog.setConvertFile(attachName);
								traffLog.setType("RD");
								registeredLog.setTimeEntry(
										TransactionManager.recvRdStatus,
										traffLog, "");
								sendJPMC(registeredLog, traffLog, "");
							} else {
								WorkerManager.reportId(converId, cmd);
								return;
							}
						}
					} else {
						// report to remove flag lock because the file is
						// duplicated
						WorkerManager.reportId(converId, cmd);
						return;
					}
				} else {
					WorkerManager.reportId(converId, cmd);
					return;
				}
			} else {
				// report to remove flag lock because it can't start task
				// without attach file
				WorkerManager.reportId(converId, cmd);
				return;
			}
		}
	}

	// separate to use for resend feature
	// need to logging the resend event if use this method to resend

	public String sendJPMC(TransactionLog log, TransactionTraffic traff,
			String type) {
		String converId = log.getConverId();
		File ctrlFile = new File(WorkerManager.TCDRecvDir + "/"
				+ traff.getTcdCtrl());
		File attach = new File(WorkerManager.TCDRecvDir + "/"
				+ traff.getTcdAttach());
		if (attach.exists()) {
			// must backup to database via blob in table archived
			TransactionManager manager = new TransactionManager();
			Integer transactionId = log.getId();
			manager.insertArchivedToDB(ctrlFile, transactionId);
			manager.insertArchivedToDB(attach, transactionId);

			// update begin transfer time
			if (log.getActionType() != null
					&& log.getActionType()
							.equals(WorkerManager.ActionTCDToBank)) {
				if (type.equals(""))
					log.setTimeEntry(TransactionManager.beginSendJpmcStatus,
							traff, type);
				else
					log.setTimeEntry(TransactionManager.resendSFTPStatus,
							traff, type);
			} else if (log.getActionType() != null
					&& log.getActionType().equals(WorkerManager.ActionRDToBank)) {
				if (type.equals(""))
					log.setTimeEntry(TransactionManager.beginSendJpmcStatusRD,
							traff, type);
				else
					log.setTimeEntry(TransactionManager.resendSFTPStatusRD,
							traff, type);
			} else {
				// report to remove flag lock because it can't send files
				WorkerManager.reportId(converId, cmd);
				return "error";
			}

			SFTPManager sftp = new SFTPManager();
			File srcAttachFile = new File(WorkerManager.TCDRecvDir + "/"
					+ attachName);
			boolean attachSucceed = false;
			attachSucceed = sftp.sendSFTPFile(srcAttachFile, traff
					.getConvertFile());
			if (attachSucceed) {
				if (log.getActionType() != null
						&& log.getActionType().equals(
								WorkerManager.ActionTCDToBank)) {
					if (type.equals(""))
						log.setTimeEntry(TransactionManager.finSendJpmcStatus,
								traff, type);
					else
						log.setTimeEntry(
								TransactionManager.resendFinSFTPStatus, traff,
								type);
				} else {
					if (type.equals(""))
						log.setTimeEntry(
								TransactionManager.finSendJpmcStatusRD, traff,
								type);
					else
						log.setTimeEntry(
								TransactionManager.resendFinSFTPStatusRD,
								traff, type);
				}
				// report to remove flag lock after finish
				WorkerManager.reportId(converId, cmd);
				return "success";
			} else {
				// report to remove flag lock because it can't send files
				WorkerManager.reportId(converId, cmd);
				return "error";
			}
			// report to remove flag lock because it doesn't have xml file
		} else {
			WorkerManager.reportId(converId, cmd);
			return "error";
		}
	}

	private void recvJPMC() {
		String converId = "";
		String[] cut = attachName.split("[--.]");
		if (cut.length > 2) {
			converId = cut[1];
		}
		TransactionManager manager = new TransactionManager();
		TransactionLog registeredLog = manager
				.findTransactionByAttach(attachName);

		// use to check was it process before
		if (registeredLog != null) {
			TransactionTraffic traff = manager
					.findTraffJpmcAttachByTransactionId(registeredLog.getId());
			traff.setTransactionId(registeredLog.getId());
			traff.setTcdAttach(null);
			traff.setTcdCtrl(null);
			traff.setTcdMsgId(null);
			if (traff.getJpmcAttach() != null) {
				WorkerManager.reportId(converId, cmd);
			} else {
				traff.insertJpmcDetail(attachName, registeredLog);
				sendTCD(registeredLog, traff, "");
			}
		} else {
			WorkerManager.reportId(converId, cmd);
		}
	}
	
	// type tcd send by sftp
	// type rd send by http post
	public String sendTCD(TransactionLog log, TransactionTraffic traff,
			String type) {
		String converId = "";
		String[] cut = attachName.split("[--.]");
		if (cut.length > 2) {
			converId = cut[1];
		}

		TransactionManager manager = new TransactionManager();
		
		if (log.getActionType() != null
				&& log.getActionType().equals(WorkerManager.ActionBankToTCD)) {
			traff.setType("TCD");
			if (type.equals(""))
				log
						.setTimeEntry(TransactionManager.recvJpmcStatus, traff,
								type);
			else
				log.setTimeEntry(TransactionManager.redownloadSFTPStatus,
						traff, type);

			ctrlName = traff.getJpmcCtrl();

			File ctrlFile = new File(WorkerManager.JPMCRecvDir + "/" + ctrlName);
			log.createJpmcCtrlFile(ctrlFile, traff);

			// need to get attachFile from sftp to temp dir before continue
			SFTPManager sftpManager = new SFTPManager();
			File tempAttachfile = new File(WorkerManager.JPMCRecvDir + "/"
					+ attachName);

			boolean attachSucceed = false;
			attachSucceed = sftpManager.getSFTPFile(attachName, tempAttachfile);

			if (attachSucceed) {
				Integer transactionId = log.getId();
				// must backup to database via blob in table archived
				TransactionManager TransManager = new TransactionManager();

				TransManager.insertArchivedToDB(ctrlFile, transactionId);
				TransManager.insertArchivedToDB(tempAttachfile, transactionId);

				// copy only attach file because ctrl file was generated in the
				// destination

				File attachFileDes = new File(WorkerManager.JPMCDesDir + "/"
						+ attachName);
				File ctrlFileDes = new File(WorkerManager.JPMCDesDir + "/"
						+ ctrlName);

				boolean sendTCD = false;

				try {
					fileMng.copyFile(tempAttachfile, attachFileDes);
					fileMng.copyFile(ctrlFile, ctrlFileDes);
					sendTCD = true;
				} catch (IOException e) {
					e.printStackTrace();
				}

				if (sendTCD) {
					if (type.equals(""))
						log.setTimeEntry(TransactionManager.sendTcdStatus,
								traff, type);
					else
						log.setTimeEntry(
								TransactionManager.redownloadFinSFTPStatus,
								traff, type);

					// report finish job
					WorkerManager.reportId(converId, cmd);
					return "success";
				} else {
					WorkerManager.reportId(converId, cmd);
					return "error";
				}
			} else {
				// report to unlock task and wait for next operate time
				WorkerManager.reportId(converId, cmd);
				return "error";
			}

		} else if (log.getActionType() != null
				&& log.getActionType().equals(WorkerManager.ActionBankToRD)) {
			traff.setType("RD");
			if (type.equals(""))
				log.setTimeEntry(TransactionManager.recvJpmcStatusRD, traff,
						type);
			else
				log.setTimeEntry(TransactionManager.redownloadSFTPStatusRD,
						traff, type);

			// need to get attachFile from sftp to temp dir before continue
			SFTPManager sftpManager = new SFTPManager();
			File tempAttachfile = new File(WorkerManager.JPMCRecvDir + "/"
					+ attachName);

			boolean attachSucceed = false;
			attachSucceed = sftpManager.getSFTPFile(attachName, tempAttachfile);

			if (attachSucceed) {
				Integer transactionId = log.getId();
				TransactionManager TransManager = new TransactionManager();
				TransManager.insertArchivedToDB(tempAttachfile, transactionId);
			}

			File postFile = new File(WorkerManager.JPMCRecvDir + "/"
					+ attachName);

			String dataFile = readFile(postFile);

			String myUrl = null;
			String resultTrack = "";

			myUrl = WorkerManager.RDPostUrl + "?attachFile=" + attachName
					+ "&converId=" + converId + "dataFile=" + dataFile;
			// myUrl =
			// WorkerManager.NetbayTrackUrl+"?USERNAME="+WorkerManager.NetbayTrackUser+"&PASSWORD="+WorkerManager.NetbayTrackPassword+"&SRID="+converId;
			try {
				resultTrack = doHttpUrlConnectionAction(myUrl);
				if (type.equals(""))
					log.setTimeEntry(TransactionManager.sendRdStatus, traff,
							type);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			resultTrack = resultTrack.trim();

			if (resultTrack.equals(converId)) {
				if (type.equals(""))
					log.setTimeEntry(TransactionManager.finSendRdStatus, traff,
							type);
				else
					log.setTimeEntry(
							TransactionManager.redownloadFinSFTPStatusRD,
							traff, type);

				// report finish job
				WorkerManager.reportId(converId, cmd);
				return "success";
			} else {
				System.out.println("Http post already but don't have ack");
				WorkerManager.reportId(converId, cmd);
				return "error";
			}
		} else {
			WorkerManager.reportId(converId, cmd);
			return "error";
		}

		// ctrlName = traff.getJpmcCtrl();
		//		
		// File ctrlFile = new File(WorkerManager.JPMCRecvDir + "/" + ctrlName);
		// log.createJpmcCtrlFile(ctrlFile,traff);
		//		
		// // need to get attachFile from sftp to temp dir before continue
		// SFTPManager sftpManager = new SFTPManager();
		// File tempAttachfile = new File(WorkerManager.JPMCRecvDir + "/"
		// + attachName);
		//		
		// boolean attachSucceed = false;
		// attachSucceed = sftpManager.getSFTPFile(attachName, tempAttachfile);
		//		
		// if (attachSucceed) {
		// Integer transactionId = log.getId();
		// // must backup to database via blob in table archived
		// TransactionManager TransManager = new TransactionManager();
		//			
		// TransManager.insertArchivedToDB(ctrlFile,transactionId);
		// TransManager.insertArchivedToDB(tempAttachfile,transactionId);
		//
		// // copy only attach file because ctrl file was generated in the
		// // destination
		//
		// File attachFileDes = new File(WorkerManager.JPMCDesDir + "/"
		// + attachName);
		// File ctrlFileDes = new File(WorkerManager.JPMCDesDir + "/"
		// + ctrlName);
		//
		// boolean sendTCD = false;
		//			
		// try {
		// fileMng.copyFile(tempAttachfile, attachFileDes);
		// fileMng.copyFile(ctrlFile, ctrlFileDes);
		// sendTCD = true;
		// } catch (IOException e) {
		// e.printStackTrace();
		// }
		//			
		//			
		//
		// if (sendTCD) {
		// if(log.getActionType() != null &&
		// log.getActionType().equals(WorkerManager.ActionBankToTCD)){
		// if(type.equals(""))log.setTimeEntry(TransactionManager.sendTcdStatus,traff,type);
		// else
		// log.setTimeEntry(TransactionManager.redownloadFinSFTPStatus,traff,type);
		// }else if(log.getActionType() != null &&
		// log.getActionType().equals(WorkerManager.ActionBankToRD)){
		// if(type.equals(""))log.setTimeEntry(TransactionManager.sendRdStatus,traff,type);
		// else
		// log.setTimeEntry(TransactionManager.redownloadFinSFTPStatusRD,traff,type);
		// }else{
		// WorkerManager.reportId(converId, cmd);
		// return "error";
		// }
		// // report finish job
		// WorkerManager.reportId(converId, cmd);
		// return "success";
		// }
		// else{
		// WorkerManager.reportId(converId, cmd);
		// return "error";
		// }
		// } else {
		// // report to unlock task and wait for next operate time
		// WorkerManager.reportId(converId, cmd);
		// return "error";
		// }
	}

	private static String readFile(File file) {
		String dataFile = "";
		try {
			// Open the file that is the first
			// command line parameter
			FileInputStream fstream = new FileInputStream(file);
			// Get the object of DataInputStream
			DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String strLine;
			// Read File Line By Line
			while ((strLine = br.readLine()) != null) {
				dataFile = dataFile + strLine;
			}
			// Close the input stream
			in.close();
		} catch (Exception e) {// Catch exception if any
			e.printStackTrace();
		}
		return dataFile;
	}

	private static String doHttpUrlConnectionAction(String desiredUrl)
			throws Exception {
		URL url = null;
		BufferedReader reader = null;
		StringBuilder stringBuilder;
		try {
			// create the HttpURLConnection
			url = new URL(desiredUrl);
			HttpURLConnection connection = (HttpURLConnection) url
					.openConnection();

			// just want to do an HTTP GET here
			connection.setRequestMethod("POST");

			// uncomment this if you want to write output to this url
			// connection.setDoOutput(true);

			// give it 15 seconds to respond
			connection.setReadTimeout(15 * 1000);
			connection.connect();

			// read the output from the server
			reader = new BufferedReader(new InputStreamReader(connection
					.getInputStream()));
			stringBuilder = new StringBuilder();

			String line = null;
			while ((line = reader.readLine()) != null) {
				stringBuilder.append(line + "\n");
			}
			return stringBuilder.toString();
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			// close the reader; this can throw an exception too, so
			// wrap it in another try/catch block.
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException ioe) {
					ioe.printStackTrace();
				}
			}
		}
	}

	public static String convertTCDToJPMC(String fileName) {
		String[] cutFileName = fileName.split("[_\\-.]");

		String sendFileName = "";
		sendFileName += cutFileName[0];
		sendFileName += "-";
		sendFileName += cutFileName[2];
		sendFileName += "-";
		sendFileName += cutFileName[1].substring(6, 20);
		sendFileName += ".xml";

		return sendFileName;
	}

	/*
	 * public static String convertJPMCToTCD (String fileName){ String[]
	 * cutFileName = fileName.split("[--.]"); String sendFileName = "";
	 * sendFileName += cutFileName[0]; sendFileName += "_Action"; sendFileName
	 * += cutFileName[2]; sendFileName += "000-"; sendFileName +=
	 * cutFileName[1]; sendFileName += ".xml"; return sendFileName; }
	 */
}
